package com.briup.day09;

public class Super {

    static {
        System.out.println("这是父类的静态代码块");
    }

    {
        System.out.println("这是父类的成员代码块");
    }

    public Super() {
        System.out.println("这是父类的无参构造器");
    }
}

class Sub extends Super {
    static {
        Sub sub = new Sub();
        // 子类的构造器执行完毕之后，子类对象才算是创建完毕
        System.out.println("==================");
        System.out.println("这是子类的静态代码块");
    }

    {
        System.out.println("这是子类的成员代码块");
    }

    public Sub() {
        System.out.println("这是子类的无参构造器");
    }
}


class Test {
    // 静态代码块是随着类的加载而执行的，是从上到下顺序执行的
    static {
        System.out.println("这是Test类的静态代码块");
        System.out.println("=======================");
    }

    public static void main(String[] args) {
        /*
            1、要创建Sub类的对象，必须先将Sub类加载到JVM方法区中，
            2、在加载Sub类的过程中，发现Sub类有一个父类Super类，
            3、所以先会将Super类加载到方法区中，在加载Super类的过程中，
            会执行Super类中的静态代码块①
            4、在加载完毕Super类后，会继续加载Sub类，然后在加载Sub类的过程中，
            会执行Sub类中的静态代码块②
            5、在加载完毕Sub类后，就可以执行Sub类的构造器创建Sub类对象；
            6、由于在子类的构造器中的首行会默认调用父类的无参构造器，而成员代码块
            是随着构造器的执行而先于构造器执行的，所以会先执行父类的成员代码块③
            7、父类的成员代码块执行完毕之后，继续执行父类的无参构造器④
            8、父类的无参构造器执行完毕后，继续回到子类的构造器执行，先执行子类的
            成员代码块⑤
            9、子类成员代码块执行完毕之后，继续执行子类的构造器⑥
         */
        Sub sub = new Sub();
    }
}